package com.yichen;

import com.yichen.entity.*;
import freemarker.template.Configuration;
import freemarker.template.Template;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Classname TemplateGenerate
 * @Description
 * @Author caozhenhao001
 * @Date 2024/6/4
 * @Version
 */
public class TemplateGenerate {

    private static final String TEMPLATE_PATH = "src/main/resources/template/default";
    private static final String JAVA_PREFIX_PATH = "src\\main\\java\\";
    private static final String RESOURCE_PREFIX_PATH = "src\\main\\resources\\";
    private static String packagePath = "com.yichen.springbootdemo.test";
    private static String filePath = "D:\\caozhenhao001\\Desktop\\";
    private static String tableName = "intermediary_product";

    private static Map<String, String> packagePathMapping = new HashMap<>(){{
        put("bo", packagePath + ".api");
        put("searchBo", packagePath + ".api");
        put("po", packagePath+ ".internal.entity");
        put("searchPo", packagePath+ ".internal.entity");
        put("service", packagePath + ".api");
        put("serviceImpl", packagePath + ".internal.impl");
        put("mapper", packagePath + ".internal.mapper");
        put("mapperXML", RESOURCE_PREFIX_PATH + "mappers");
        put("repository", packagePath + ".internal.repository");
        put("controller", packagePath + ".web");
        put("searchVo", packagePath + ".web.vo");
        put("vo", packagePath + ".web.vo");
        put("innerTransferUtil", packagePath + ".utils");
    }};

    public static void templateGenerate(String fileName, String templateFile, Map<String, Object> dataMap) {
        Configuration configuration = new Configuration();
        Writer out = null;
        try {
            configuration.setDirectoryForTemplateLoading(new File(TEMPLATE_PATH));
            Template template = configuration.getTemplate(templateFile + ".ftl");
            String generatePath = "";
            if ("mapperXML".equals(templateFile)) {
                generatePath = filePath + packagePathMapping.get(templateFile) + "\\" + fileName;
            } else {
                generatePath = filePath + JAVA_PREFIX_PATH + packagePathMapping.get(templateFile).replace(".","\\") + "\\"+ fileName;
            }
            File docFile = new File(generatePath);
            docFile.getParentFile().mkdirs();
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));
            template.process(dataMap, out);
            System.out.println(fileName + "创建成功 !");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != out) {
                    out.flush();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }

    public static Map<String , Object> getDataMap(){
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("package", packagePath);   // 包路径（公共部分）
        dataMap.put("tableName", tableName);   // 数据库表名
        List<QueryCondition> queryConditionList = getQuerySearch();
        dataMap.put("queryConditionList", queryConditionList);              // 添加查询配置
        dataMap.put("entityName", Utils.convertSnakeToCamel(tableName));
        for (Map.Entry<String, String> entry: packagePathMapping.entrySet()) {
            dataMap.put(entry.getKey() + "PackagePath", entry.getValue());   // 每个文件的完整包路径
        }
        List<TableFieldInfo> tableFieldInfoList = DataBaseUtil.getTableFieldInfo(tableName);
        List<ClassFieldInfo> classFieldInfoList = DataBaseUtil.convertTableToClass(tableFieldInfoList);
        dataMap.put("classFieldInfoList", classFieldInfoList);      // 驼峰形式的数据库表字段
        return dataMap;
    }

    /**
     * 设置条件查询的实体类的属性，以及查询的方式
     * @return
     */
    public static List<QueryCondition> getQuerySearch() {
        List<QueryCondition> queryConditionList = new ArrayList<>();
//        queryConditionList.add(new QueryCondition("username", JavaTypeEnum.STRING, QueryTypeEnum.LIKE));
//        queryConditionList.add(new QueryCondition("sex", JavaTypeEnum.STRING, QueryTypeEnum.EQUALS));
//        queryConditionList.add(new QueryCondition("age", JavaTypeEnum.INTEGER, QueryTypeEnum.LESS_THAN_OR_EQUALS, "ageMax"));
//        queryConditionList.add(new QueryCondition("age", JavaTypeEnum.INTEGER, QueryTypeEnum.GREATER_THAN, "ageMin"));
//        queryConditionList.add(new QueryCondition("height", JavaTypeEnum.INTEGER, QueryTypeEnum.EQUALS));
//        queryConditionList.add(new QueryCondition("weightS", JavaTypeEnum.INTEGER, QueryTypeEnum.EQUALS));

        queryConditionList.add(new QueryCondition("id", JavaTypeEnum.LONG, QueryTypeEnum.EQUALS));
        queryConditionList.add(new QueryCondition("productName", JavaTypeEnum.STRING, QueryTypeEnum.LIKE));
        queryConditionList.add(new QueryCondition("minAnnualInterestRate", JavaTypeEnum.INTEGER, QueryTypeEnum.LESS_THAN_OR_EQUALS, "max"));
        queryConditionList.add(new QueryCondition("minAnnualInterestRate", JavaTypeEnum.INTEGER, QueryTypeEnum.GREATER_THAN, "min"));
//        queryConditionList.add(new QueryCondition("height", JavaTypeEnum.INTEGER, QueryTypeEnum.EQUALS));
//        queryConditionList.add(new QueryCondition("weightS", JavaTypeEnum.INTEGER, QueryTypeEnum.EQUALS));
        return queryConditionList;
    }

    public static void codeGenerate(){
        String tableNameCamel = Utils.convertSnakeToCamel(tableName);
        String[] generateFileList = new String[]{"controller", "bo", "searchBo", "po", "searchPo",  "mapper",
                "mapperXML", "service", "serviceImpl", "repository", "innerTransferUtil", "searchVo", "vo"};

        Map<String, Object> dataMap = getDataMap();
        for (String file : generateFileList) {
            if("mapperXML".equals(file)) {       // 生成XML文件
                templateGenerate(Utils.capFirst(tableNameCamel) + "Mapper.xml", file, dataMap);
            } else if (file.endsWith("Util")) {    // 生成工具文件（类名不加实体前缀）
                templateGenerate(Utils.capFirst(file) + ".java", file, dataMap);
            } else {                               // 生成其他java文件
                templateGenerate(Utils.capFirst(tableNameCamel) + Utils.capFirst(file) + ".java", file, dataMap);
            }

        }
    }

    public static void main(String[] args) {
        codeGenerate();
    }
}
